package net.jgrm.product.service.impl;

import com.alicp.jetcache.anno.CacheInvalidate;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.CacheUpdate;
import com.alicp.jetcache.anno.Cached;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.jgrm.idgenerator.service.IdGenerator;
import net.jgrm.product.entity.Product;
import net.jgrm.product.mapper.ProductMapper;
import net.jgrm.product.service.IProductService;
import net.jgrm.product.service.IProductStockService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.net.InetAddress;
import java.time.LocalDateTime;
import java.util.List;


/**
 * 商品服务实现类（优化后架构）
 * <p>
 * 职责重新定位：
 * 1. 管理商品基本信息的缓存（product-info）
 * 2. 处理商品数据的CRUD操作
 * 3. 与ProductStockService配合提供完整的商品数据
 * <p>
 * 缓存策略：
 * - ProductService: product-info缓存（商品基本信息，长时间缓存）
 * - ProductStockService: product-stock缓存（库存信息，短时间缓存）
 * <p>
 * 调用链：
 * Controller → ProductService (product-info缓存) + ProductStockService (product-stock缓存)
 * <p>
 * 优势：
 * 1. 职责清晰：每个服务管理自己领域的缓存
 * 2. 架构简洁：去掉冗余的中间缓存层
 * 3. 性能优化：商品信息和库存信息独立缓存
 */
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {
    private static final Logger logger = LoggerFactory.getLogger(ProductServiceImpl.class);
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private IdGenerator idGenerator;
    @Autowired
    private IProductStockService productStockService;

    private String instanceId;

    @PostConstruct
    public void init() {
        try {
            instanceId = InetAddress.getLocalHost().getHostName() + "-" + System.currentTimeMillis() % 10000;
        } catch (Exception e) {
            instanceId = "unknown-" + System.currentTimeMillis() % 10000;
        }
        logger.info("ProductServiceImpl initialized on instance: {}", instanceId);
    }

    /**
     * 获取商品信息（带product-info缓存）
     * 缓存商品基本信息，不包含库存字段
     */
    @Override
    @Cached(
            name = "product-info",
            key = "#id",
            expire = 300,  // 5分钟过期
            localExpire = 60,  // 本地缓存1分钟
            cacheType = CacheType.BOTH,
            syncLocal = true
    )
    @DS("slave1")
    public Product getProductById(Long id) {
        logger.info("Instance {} loading product {} from database (with product-info cache)", instanceId, id);

        Product product = baseMapper.selectById(id);
        if (product == null) {
            throw new RuntimeException("商品不存在: " + id);
        }

        // 注意：缓存中不包含库存信息，库存由ProductStockService单独管理
        // 如果需要完整信息，在上层组合获取
        logger.debug("Successfully loaded product {} from cache/database", id);
        return product;
    }

    /**
     * 扣减库存（优化版：使用专门的库存服务）
     * 不再影响商品基本信息缓存，提高性能
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean decreaseStock(Long productId, Integer quantity) {
        logger.info("Instance {} decreasing stock for product {} by {} using optimized stock service",
                instanceId, productId, quantity);

        boolean b = productStockService.decreaseStock(productId, quantity);
        return b;

    }

    /**
     * 保存商品（同时管理缓存）
     */
    @Cached(
            name = "product-info",
            key = "#product",
            expire = 300,  // 5分钟过期
            localExpire = 60,  // 本地缓存1分钟
            cacheType = CacheType.BOTH,
            syncLocal = true
    )
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Product saveProduct(Product product) {
        logger.info("Instance {} creating new product", instanceId);

        // 生成ID
        Long id = idGenerator.nextId("product");
        product.setId(id);
        product.setCreateTime(LocalDateTime.now());
        product.setUpdateTime(LocalDateTime.now());

        // 插入数据库
        baseMapper.insert(product);

        // 同步库存到库存服务
        if (product.getStock() != null && product.getStock() > 0) {
            productStockService.setStock(id, product.getStock());
        }

        logger.debug("Successfully saved product: {}", id);
        return product;
    }

    /**
     * 删除商品（同时清理缓存）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheInvalidate(
            name = "product-info",
            key = "#productId"
    )
    public void removeById(Long productId) {
        logger.info("Instance {} removing product {} and invalidating cache", instanceId, productId);

        // 删除数据库记录
        productMapper.removeById(productId);

        logger.debug("Successfully removed product: {}", productId);
    }

    /**
     * 批量删除商品（同时批量清理缓存）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeProductByIds(List<Long> productIds) {
        if (productIds == null || productIds.isEmpty()) {
            return;
        }
        logger.info("Instance {} removing {} products and invalidating caches", instanceId, productIds.size());

        // 批量删除数据库记录
        productMapper.deleteByIds(productIds);

        // 批量清理缓存
        for (Long productId : productIds) {
            // 手动清理product-info缓存（批量操作无法使用注解）
            invalidateProductInfoCache(productId);
        }

        logger.debug("Successfully removed products: {}", productIds);
    }


    /**
     * 更新商品（同时更新缓存）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheUpdate(
            name = "product-info",
            key = "#product.id",
            value = "#result"
    )
    public Product updateProductById(Product product) {
        logger.info("Instance {} updating product {} and refreshing cache", instanceId, product.getId());

        Product productExist = productMapper.selectById(product.getId());
        if (productExist == null) {
            throw new RuntimeException("商品不存在");
        }

        // 更新数据库
        product.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(product);

        // 如果库存有变化，同步到库存服务
        if (product.getStock() != null) {
            productStockService.setStock(product.getId(), product.getStock());
        }

        // 重新查询最新数据返回
        Product updatedProduct = productMapper.selectById(product.getId());

        logger.debug("Successfully updated product: {}", product.getId());
        return updatedProduct;
    }

    /**
     * 获取实例标识
     */
    public String getInstanceId() {
        return instanceId;
    }

    /**
     * 手动清理product-info缓存
     * 用于批量操作等无法使用注解的场景
     */
    @CacheInvalidate(
            name = "product-info",
            key = "#productId"
    )
    public void invalidateProductInfoCache(Long productId) {
        logger.debug("Manually invalidating product-info cache for product: {}", productId);
        // JetCache会自动处理缓存清理
    }

}